import {designPage, getComponentCls, reactive, useRefs} from "plain-design-composition";
import data50 from '../../../data/data-50.json';
import {iTableCellRenderScope, iTableNode} from "../../../../packages/components/Table/table/utils/table.utils";
import {$message, Button, ButtonGroup, Form, FormItem, Plc, PlcCheckbox, PlcIndex, PlcInput, PlcSelect, PlcSwitch, SelectOption, Table} from "../../../../packages";
import {DemoRow} from "../../Demo/DemoRow";

export const demo1 = designPage(() => {

  const { refs, onRef } = useRefs({
    table: Table
  });

  const state = reactive({
    data: data50.slice(0, 5),
    editNodes: [] as iTableNode[],

    onDblClickRow(tableNode: iTableNode) {
      if (!tableNode.state.edit) {
        tableNode.enableEdit();
        state.editNodes.push(tableNode);
      }
    },
    saveEdit: async () => {
      const validates = (await Promise.all(state.editNodes.map(node => node.validate()))).filter(Boolean);
      if (validates.length > 0) {
        console.log(validates);
        const { validateResultData, node: { state: { index } } } = validates[0]!;
        $message.error(`第${index + 1}条记录校验不通过，${validateResultData[0].label}:${validateResultData[0].message}`);
        return;
      }
      // todo 网络保存逻辑
      state.editNodes.forEach(tableNode => tableNode.saveEdit(tableNode.state.editRow));
      state.editNodes.forEach(tableNode => tableNode.closeEdit());
      state.editNodes = [];
    },
    cancelEdit: () => {
      state.editNodes.forEach(tableNode => {
        tableNode.cancelEdit();
      });
      state.editNodes = [];
    },
  });

  const statusOptions = [
    { label: '基础', status: 'primary' },
    { label: '成功', status: 'success' },
    { label: '警告', status: 'warn' },
    { label: '错误', status: 'error' },
    { label: '通知', status: 'secondary' },
  ];

  return () => (
    <DemoRow title={'基本用法'}>
      <Form column={1}>
        <FormItem label="导出">
          <ButtonGroup style={{ margin: '4px 0' }}>
            <Button label="导出原始数据" onClick={() => console.log(refs.table!.methods.getSourceData())}/>
            <Button label="导出显示数据" onClick={() => refs.table!.methods.getShowData().then(val => console.log(val))}/>
          </ButtonGroup>
        </FormItem>
        <FormItem label={'编辑'}>
          <ButtonGroup disabled={state.editNodes.length === 0}>
            <Button onClick={state.saveEdit} label={'保存编辑'}/>
            <Button onClick={state.cancelEdit} label={'取消编辑'}/>
          </ButtonGroup>
        </FormItem>
      </Form>
      <Table
        data={state.data}
        onDblclickCell={state.onDblClickRow}
        ref={onRef.table}
      >
        <PlcIndex/>
        <Plc field="id" title="编号"/>
        <PlcInput field="name" title="文本框" required/>
        <PlcSwitch field={'flag'} title={'开关'}/>
        <PlcCheckbox field={'flag'} title={'开关'}/>
        <PlcSelect field="status" title="下拉选择">
          {statusOptions.map((item) => (
            <SelectOption children={item.label} value={item.status} key={item.status}/>
          ))}
        </PlcSelect>
      </Table>
    </DemoRow>
  );
});


export const demo2 = designPage(() => {

  const { refs, onRef } = useRefs({
    table: Table
  });

  const state = reactive({
    data: data50.slice(0, 5),
    editNodes: [] as iTableNode[],

    onDblClickRow(tableNode: iTableNode) {
      if (!tableNode.state.edit) {
        tableNode.enableEdit();
        state.editNodes.push(tableNode);
      }
    },
    saveEdit: async () => {
      const validates = (await Promise.all(state.editNodes.map(node => node.validate()))).filter(Boolean);
      if (validates.length > 0) {
        console.log(validates);
        const { validateResultData, node: { state: { index } } } = validates[0]!;
        $message.error(`第${index + 1}条记录校验不通过，${validateResultData[0].label}:${validateResultData[0].message}`);
        return;
      }
      // todo 网络保存逻辑
      state.editNodes.forEach(tableNode => tableNode.saveEdit(tableNode.state.editRow));
      state.editNodes.forEach(tableNode => tableNode.closeEdit());
      state.editNodes = [];
    },
    cancelEdit: () => {
      state.editNodes.forEach(tableNode => {
        tableNode.cancelEdit();
      });
      state.editNodes = [];
    },
  });

  const statusOptions = [
    { label: '基础', status: 'primary' },
    { label: '成功', status: 'success' },
    { label: '警告', status: 'warn' },
    { label: '错误', status: 'error' },
    { label: '通知', status: 'secondary' },
  ];

  return () => (
    <DemoRow title={'选项显示格式化'}>
      <Form column={1}>
        <FormItem label="导出">
          <ButtonGroup style={{ margin: '4px 0' }}>
            <Button label="导出原始数据" onClick={() => console.log(refs.table!.methods.getSourceData())}/>
            <Button label="导出显示数据" onClick={() => refs.table!.methods.getShowData().then(val => console.log(val))}/>
          </ButtonGroup>
        </FormItem>
        <FormItem label={'编辑'}>
          <ButtonGroup disabled={state.editNodes.length === 0}>
            <Button onClick={state.saveEdit} label={'保存编辑'}/>
            <Button onClick={state.cancelEdit} label={'取消编辑'}/>
          </ButtonGroup>
        </FormItem>
      </Form>
      <Table
        data={state.data}
        onDblclickCell={state.onDblClickRow}
        ref={onRef.table}
      >
        <PlcIndex/>
        <Plc field="id" title="编号"/>
        <PlcInput field="name" title="文本框" required/>
        <PlcSwitch field={'flag'} title={'开关'}/>
        <PlcCheckbox field={'flag'} title={'开关'}/>
        <PlcSelect field="status" title="下拉选择(正常)">
          {statusOptions.map((item) => (
            <SelectOption value={item.status} key={item.status}>
              <span style={{ display: 'inline-block', verticalAlign: '0', height: '10px', width: '10px', borderRadius: '10px', marginRight: '4px', backgroundColor: `var(--${getComponentCls(`color${item.status.charAt(0).toUpperCase() + item.status.slice(1) + (item.status === 'warn' ? 'ing' : '')}Text`)})` }}/>
              <span style={{ display: 'inline-block', marginRight: '8px' }}>{item.label}</span>
            </SelectOption>
          ))}
        </PlcSelect>
        <PlcSelect field="status" title="下拉选择(使用选项内容渲染)" useOptionRenderNormal width={220}>
          {statusOptions.map((item) => (
            <SelectOption value={item.status} key={item.status}>
              <span style={{ display: 'inline-block', verticalAlign: '0', height: '10px', width: '10px', borderRadius: '10px', marginRight: '4px', backgroundColor: `var(--${getComponentCls(`color${item.status.charAt(0).toUpperCase() + item.status.slice(1) + (item.status === 'warn' ? 'ing' : '')}Text`)})` }}/>
              <span style={{ display: 'inline-block', marginRight: '8px' }}>{item.label}</span>
            </SelectOption>
          ))}
        </PlcSelect>
      </Table>
    </DemoRow>
  );
});


export const demo3 = designPage(() => {

  const { refs, onRef } = useRefs({
    table: Table
  });

  const state = reactive({
    data: data50.slice(0, 5),
    editNodes: [] as iTableNode[],

    onDblClickRow(tableNode: iTableNode) {
      if (!tableNode.state.edit) {
        tableNode.enableEdit();
        state.editNodes.push(tableNode);
      }
    },
    saveEdit: async () => {
      const validates = (await Promise.all(state.editNodes.map(node => node.validate()))).filter(Boolean);
      if (validates.length > 0) {
        console.log(validates);
        const { validateResultData, node: { state: { index } } } = validates[0]!;
        $message.error(`第${index + 1}条记录校验不通过，${validateResultData[0].label}:${validateResultData[0].message}`);
        return;
      }
      // todo 网络保存逻辑
      state.editNodes.forEach(tableNode => tableNode.saveEdit(tableNode.state.editRow));
      state.editNodes.forEach(tableNode => tableNode.closeEdit());
      state.editNodes = [];
    },
    cancelEdit: () => {
      state.editNodes.forEach(tableNode => {
        tableNode.cancelEdit();
      });
      state.editNodes = [];
    },
  });

  const statusOptions = [
    { label: '基础', status: 'primary' },
    { label: '成功', status: 'success' },
    { label: '警告', status: 'warn' },
    { label: '错误', status: 'error' },
    { label: '通知', status: 'secondary' },
  ];

  const dynamicFormatter = (value: any, cellRenderScope: Omit<iTableCellRenderScope, 'node'>) => {
    const { row } = cellRenderScope;
    if (!value) {return;}
    const label = statusOptions.find(i => i.status === value)?.label;
    if (!label) {return null;}
    return row.flag === 'Y' ? `<<${label}>>` : label;
  };

  return () => (
    <DemoRow title={'动态选项'}>
      <Form column={1}>
        <FormItem label="导出">
          <ButtonGroup style={{ margin: '4px 0' }}>
            <Button label="导出原始数据" onClick={() => console.log(refs.table!.methods.getSourceData())}/>
            <Button label="导出显示数据" onClick={() => refs.table!.methods.getShowData().then(val => console.log(val))}/>
          </ButtonGroup>
        </FormItem>
        <FormItem label={'编辑'}>
          <ButtonGroup disabled={state.editNodes.length === 0}>
            <Button onClick={state.saveEdit} label={'保存编辑'}/>
            <Button onClick={state.cancelEdit} label={'取消编辑'}/>
          </ButtonGroup>
        </FormItem>
      </Form>
      <div style={{ margin: '4px 0' }}>
        为了导出显示数据能够正常工作，需要提供列的formatter函数来得到显示值
      </div>
      <Table
        data={state.data}
        onDblclickCell={state.onDblClickRow}
        ref={onRef.table}
      >
        <PlcIndex/>
        <Plc field="id" title="编号"/>
        <PlcInput field="name" title="文本框" required/>
        <PlcSwitch field={'flag'} title={'开关'}/>
        <PlcCheckbox field={'flag'} title={'开关'}/>
        <PlcSelect
          field="status"
          title="下拉选择(动态选项，正常)"
          width={220}
          formatter={dynamicFormatter}
          v-slots={{
            dynamic: ({ row }) => (
              statusOptions.map((item) => (
                row.flag === 'Y' ? (
                  <SelectOption value={item.status} key={item.status}>
                    <span style={{ display: 'inline-block', verticalAlign: '0', height: '10px', width: '10px', borderRadius: '10px', marginRight: '4px', backgroundColor: `var(--${getComponentCls(`color${item.status.charAt(0).toUpperCase() + item.status.slice(1) + (item.status === 'warn' ? 'ing' : '')}Text`)})` }}/>
                    <span>{`<<${item.label}>>`}</span>
                  </SelectOption>
                ) : (
                  <SelectOption value={item.status} key={item.status}>
                    <span style={{ display: 'inline-block', verticalAlign: '0', height: '10px', width: '10px', borderRadius: '10px', marginRight: '4px', backgroundColor: `var(--${getComponentCls(`color${item.status.charAt(0).toUpperCase() + item.status.slice(1) + (item.status === 'warn' ? 'ing' : '')}Text`)})` }}/>
                    <span style={{ display: 'inline-block', marginRight: '8px' }}>{item.label}</span>
                  </SelectOption>
                )
              ))
            )
          }}
        />
        <PlcSelect
          field="status"
          title="下拉选择(动态选项，使用选项内容渲染)"
          width={220}
          useOptionRenderNormal
          formatter={dynamicFormatter}
          v-slots={{
            dynamic: ({ row }) => (
              statusOptions.map((item) => (
                row.flag === 'Y' ? (
                  <SelectOption value={item.status} key={item.status}>
                    <span style={{ display: 'inline-block', verticalAlign: '0', height: '10px', width: '10px', borderRadius: '10px', marginRight: '4px', backgroundColor: `var(--${getComponentCls(`color${item.status.charAt(0).toUpperCase() + item.status.slice(1) + (item.status === 'warn' ? 'ing' : '')}Text`)})` }}/>
                    <span>{`<<${item.label}>>`}</span>
                  </SelectOption>
                ) : (
                  <SelectOption value={item.status} key={item.status}>
                    <span style={{ display: 'inline-block', verticalAlign: '0', height: '10px', width: '10px', borderRadius: '10px', marginRight: '4px', backgroundColor: `var(--${getComponentCls(`color${item.status.charAt(0).toUpperCase() + item.status.slice(1) + (item.status === 'warn' ? 'ing' : '')}Text`)})` }}/>
                    <span style={{ display: 'inline-block', marginRight: '8px' }}>{item.label}</span>
                  </SelectOption>
                )
              ))
            )
          }}
        />
      </Table>
    </DemoRow>
  );
});


export const demo4 = designPage(() => {

  const { refs, onRef } = useRefs({
    table: Table
  });

  const state = reactive({
    data: data50.slice(0, 5),
    editNodes: [] as iTableNode[],

    onDblClickRow(tableNode: iTableNode) {
      if (!tableNode.state.edit) {
        tableNode.enableEdit();
        state.editNodes.push(tableNode);
      }
    },
    saveEdit: async () => {
      const validates = (await Promise.all(state.editNodes.map(node => node.validate()))).filter(Boolean);
      if (validates.length > 0) {
        console.log(validates);
        const { validateResultData, node: { state: { index } } } = validates[0]!;
        $message.error(`第${index + 1}条记录校验不通过，${validateResultData[0].label}:${validateResultData[0].message}`);
        return;
      }
      // todo 网络保存逻辑
      state.editNodes.forEach(tableNode => tableNode.saveEdit(tableNode.state.editRow));
      state.editNodes.forEach(tableNode => tableNode.closeEdit());
      state.editNodes = [];
    },
    cancelEdit: () => {
      state.editNodes.forEach(tableNode => {
        tableNode.cancelEdit();
      });
      state.editNodes = [];
    },
  });

  const statusOptions = [
    { label: '基础', status: 'primary' },
    { label: '成功', status: 'success' },
    { label: '警告', status: 'warn' },
    { label: '错误', status: 'error' },
    { label: '通知', status: 'secondary' },
  ];

  return () => (
    <DemoRow title={'多选'}>
      <Form column={1}>
        <FormItem label="导出">
          <ButtonGroup style={{ margin: '4px 0' }}>
            <Button label="导出原始数据" onClick={() => console.log(refs.table!.methods.getSourceData())}/>
            <Button label="导出显示数据" onClick={() => refs.table!.methods.getShowData().then(val => console.log(val))}/>
          </ButtonGroup>
        </FormItem>
        <FormItem label={'编辑'}>
          <ButtonGroup disabled={state.editNodes.length === 0}>
            <Button onClick={state.saveEdit} label={'保存编辑'}/>
            <Button onClick={state.cancelEdit} label={'取消编辑'}/>
          </ButtonGroup>
        </FormItem>
      </Form>
      <Table
        data={state.data}
        onDblclickCell={state.onDblClickRow}
        ref={onRef.table}
      >
        <PlcIndex/>
        <Plc field="id" title="编号"/>
        <PlcInput field="name" title="文本框" required/>
        <PlcSwitch field={'flag'} title={'开关'}/>
        <PlcCheckbox field={'flag'} title={'开关'}/>
        <PlcSelect field="statusList" title="下拉选择多选array" multiple>
          {statusOptions.map((item) => (
            <SelectOption children={item.label} value={item.status} key={item.status}/>
          ))}
        </PlcSelect>
        <PlcSelect field="statusArrayJson" title="下拉选择多选arrayjson" multiple valueType="arrayjson">
          {statusOptions.map((item) => (
            <SelectOption children={item.label} value={item.status} key={item.status}/>
          ))}
        </PlcSelect>
        <PlcSelect field="statusArrayString" title="下拉选择多选arraystring" multiple valueType="arraystring">
          {statusOptions.map((item) => (
            <SelectOption children={item.label} value={item.status} key={item.status}/>
          ))}
        </PlcSelect>
      </Table>
    </DemoRow>
  );
});


export const demo5 = designPage(() => {

  const { refs, onRef } = useRefs({
    table: Table
  });

  const state = reactive({
    data: data50.slice(0, 5),
    editNodes: [] as iTableNode[],

    onDblClickRow(tableNode: iTableNode) {
      if (!tableNode.state.edit) {
        tableNode.enableEdit();
        state.editNodes.push(tableNode);
      }
    },
    saveEdit: async () => {
      const validates = (await Promise.all(state.editNodes.map(node => node.validate()))).filter(Boolean);
      if (validates.length > 0) {
        console.log(validates);
        const { validateResultData, node: { state: { index } } } = validates[0]!;
        $message.error(`第${index + 1}条记录校验不通过，${validateResultData[0].label}:${validateResultData[0].message}`);
        return;
      }
      // todo 网络保存逻辑
      state.editNodes.forEach(tableNode => tableNode.saveEdit(tableNode.state.editRow));
      state.editNodes.forEach(tableNode => tableNode.closeEdit());
      state.editNodes = [];
    },
    cancelEdit: () => {
      state.editNodes.forEach(tableNode => {
        tableNode.cancelEdit();
      });
      state.editNodes = [];
    },
  });

  const statusOptions = [
    { label: '基础', status: 'primary' },
    { label: '成功', status: 'success' },
    { label: '警告', status: 'warn' },
    { label: '错误', status: 'error' },
    { label: '通知', status: 'secondary' },
  ];

  return () => (
    <DemoRow title={'多选，格式化选项内容'}>
      <Form column={1}>
        <FormItem label="导出">
          <ButtonGroup style={{ margin: '4px 0' }}>
            <Button label="导出原始数据" onClick={() => console.log(refs.table!.methods.getSourceData())}/>
            <Button label="导出显示数据" onClick={() => refs.table!.methods.getShowData().then(val => console.log(val))}/>
          </ButtonGroup>
        </FormItem>
        <FormItem label={'编辑'}>
          <ButtonGroup disabled={state.editNodes.length === 0}>
            <Button onClick={state.saveEdit} label={'保存编辑'}/>
            <Button onClick={state.cancelEdit} label={'取消编辑'}/>
          </ButtonGroup>
        </FormItem>
      </Form>
      <Table
        data={state.data}
        onDblclickCell={state.onDblClickRow}
        ref={onRef.table}
      >
        <PlcIndex/>
        <Plc field="id" title="编号"/>
        <PlcInput field="name" title="文本框" required/>
        <PlcSwitch field={'flag'} title={'开关'}/>
        <PlcCheckbox field={'flag'} title={'开关'}/>
        <PlcSelect field="statusList" title="下拉选择多选array" multiple useOptionRenderNormal>
          {statusOptions.map((item) => (
            <SelectOption value={item.status} key={item.status}>
              <span style={{ display: 'inline-block', verticalAlign: '0', height: '10px', width: '10px', borderRadius: '10px', marginRight: '4px', backgroundColor: `var(--${getComponentCls(`color${item.status.charAt(0).toUpperCase() + item.status.slice(1) + (item.status === 'warn' ? 'ing' : '')}Text`)})` }}/>
              <span style={{ display: 'inline-block', marginRight: '8px' }}>{item.label}</span>
            </SelectOption>
          ))}
        </PlcSelect>
        <PlcSelect field="statusArrayJson" title="下拉选择多选arrayjson" multiple valueType="arrayjson" useOptionRenderNormal>
          {statusOptions.map((item) => (
            <SelectOption value={item.status} key={item.status}>
              <span style={{ display: 'inline-block', verticalAlign: '0', height: '10px', width: '10px', borderRadius: '10px', marginRight: '4px', backgroundColor: `var(--${getComponentCls(`color${item.status.charAt(0).toUpperCase() + item.status.slice(1) + (item.status === 'warn' ? 'ing' : '')}Text`)})` }}/>
              <span style={{ display: 'inline-block', marginRight: '8px' }}>{item.label}</span>
            </SelectOption>
          ))}
        </PlcSelect>
        <PlcSelect field="statusArrayString" title="下拉选择多选arraystring" multiple valueType="arraystring" useOptionRenderNormal>
          {statusOptions.map((item) => (
            <SelectOption value={item.status} key={item.status}>
              <span style={{ display: 'inline-block', verticalAlign: '0', height: '10px', width: '10px', borderRadius: '10px', marginRight: '4px', backgroundColor: `var(--${getComponentCls(`color${item.status.charAt(0).toUpperCase() + item.status.slice(1) + (item.status === 'warn' ? 'ing' : '')}Text`)})` }}/>
              <span style={{ display: 'inline-block', marginRight: '8px' }}>{item.label}</span>
            </SelectOption>
          ))}
        </PlcSelect>
      </Table>
    </DemoRow>
  );
});
